//
//	２点を選択する
//
function private SelectEdge( prev_sel, point )
{
	var	edge;
	var	pick, prev, draw_flag = ON;
	var	key, ver, sel, point_temp[2], work_sel;
	var	i, j, k, temp, sel_temp;

	sel = Select();
	point[0] = Cursor();
	cur = point[0];
	pick = cur;
	SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
	work_sel = Select();
	Select( prev_sel );
	ver = 1;
	input_flag = OFF;
	while( TRUE )
	{
		if(( draw_flag == ON ) & ( ver ==1 ))
			DrawLine( cur, point[0] );
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if( ( ShiftStat() & 1 ) == 1 )
		{
			cur = Cursor();
			TrimCursor( point[0], MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if ( input_flag | key == INPUT_KEY )
		{
			if( ver == 0 )
			{
				Select( sel );
				SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
				if( SelectPolygons() == 0 )
				{
					Warning();
					if( novice_flag == ON )
						Message( error_msg1 );
				}
				else
				{
					point[0] = cur;
					ver++;
				}
			}
			else
			{
				if ( point[0] == cur )
				{
					Warning();
					if( novice_flag == ON )
						Message( error_msg4 );
				}
				else
				{
					Select( sel );
					SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
					if( SelectPolygons() == 0 )
					{
						Warning();
						if( novice_flag == ON )
						{
							temp = Cursor();
							if( temp != cur )
								Message( error_msg1 );
							else
								Message( "選択面中にこの点を含む面はありません" );
						}
						Select( prev_sel );
					}
					else
					{
						point[1] = cur;
						Select( work_sel | Select());
						DrawLine( point[0], point[1] );
						return TRUE;
					}
				}
			}
		}
		else if ( key == ESC )
			return FALSE;
		else if ( key == BS )
		{
			if( ver == 0 )
				return FALSE;
			else
			{
				DrawLine( pick, point[0] );
				cur = point[0];
				Cursor( cur );
				ver--;
			}
		}
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			if( ver == 1 )
				DrawLine( pick, point[0] );
			draw_flag = ON;
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		input_flag = OFF;
	}
}

//
//	面を登録する
//
function private SetPoly( org, v )
{
	var	vers, i, temp;

	PolyLoadInit();
	while( PolyLoad() )
	{
		vers = PolyVertexs();
		for( i = 0;i<vers;i++ )
		{
			temp = PolyGetVertex( i );
			if((temp == org[0] ) | ( temp == org[1] ))
			{
				if( temp == org[0] )
					PolySetVertex( temp + v[0], i );
				else
					PolySetVertex( temp + v[1], i );
			}
		}
		PolySave();
	}
}

//
//	任意の２点を結ぶ線分を平行移動する
//
function _MoveEdge()
{
	var	org[2], point[2], pos_temp[2];
	var	v[2];
	var	prev_sel, sel;
	var	edge, edge1, edge2;
	var	pick, draw_flag = ON;
	var	i, j, key;
	var	mode, temp;
	var	edges1, edges2;
	var	change_flag = OFF;
	var	vers;

	cur = Cursor();
	if (cur != PolyVertex( cur ))
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg1 );
		return ;
	}

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"移動中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【平行移動する辺を指定中】";
	DrawStatus();
	quit_flag = FALSE;

	prev_sel = Select();
	SelectAll( TRUE );
	if( SelectEdge( prev_sel, org ) == FALSE )
	{
		PopandClear( OVERWRITE );
		Select( prev_sel );
		return;
	}
	Status_title[0] = "【辺を平行移動中】";
	DrawStatus();
	sel = Select();
	edge = EdgeSelect();
	edge1 = EdgeVertex( edge, org[0] );
	edge1 = edge1 - Edge( org[0], org[1] );
	edge2 = EdgeVertex( edge, org[1] );
	edge2 = edge2 - Edge( org[0], org[1] );
	edges1 = Edges( edge1 );
	edges2 = Edges( edge2 );
	Select( prev_sel );
	cur = Cursor();
	pick = cur;
	mode = 1;
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			pos_temp[mode] = cur;
			pos_temp[1-mode] = cur+(Position(org[1-mode])- Position(org[mode]));
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if ( ShiftStat() & 1 )
		{
			cur = Cursor();
			TrimCursor( org[mode], MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
		{
			if( org[mode] == cur )
			{
				Warning();
				if( novice_flag == ON )
					Message( error_msg5 );
			}
			else
				break;
		}
		else if( key == ESC | key == BS | quit_flag == TRUE )
		{
			PopandClear( OVERWRITE );
			Select( prev_sel );
			return;
		}
		else if( key =='c' )
			change_flag = ON;
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			draw_flag = ON;
			pos_temp[mode] = pick;
			pos_temp[1-mode] = pick+(Position(org[1-mode])-Position(org[mode]));
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		if( change_flag == ON )
			mode = 1 - mode;
		change_flag = OFF;
		input_flag = OFF;
	}

	Select( sel );
	pos_temp[mode] = pick;
	pos_temp[1-mode] = pick+(Position(org[1-mode])-Position(org[mode]));
	for( i = 0; i< edges1; i++ )
	{
		EdgeGetVertex( edge1, i, point );
		if( point[0] == org[0] )
			DrawLine( pos_temp[0], point[1] );
		else
			DrawLine( pos_temp[0], point[0] );
	}
	for( i = 0; i< edges2; i++ )
	{
		EdgeGetVertex( edge2, i, point );
		if( point[0] == org[1] )
			DrawLine( pos_temp[1], point[1] );
		else
			DrawLine( pos_temp[1], point[0] );
	}
	DrawLine( pos_temp[0], pos_temp[1] );

	pos_temp[mode] = cur;
	pos_temp[1-mode] = cur+(Position(org[1-mode])-Position(org[mode]));
	v[mode] = Position(pos_temp[mode] ) - Position(org[mode]);
	v[1-mode] = Position( pos_temp[1-mode] ) - Position( org[1-mode] );
	SetPoly( org, v );
	Select( prev_sel );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

//
//	任意の２点を結ぶ線分を回転する
//
function _RotateEdge()
{
	var	org[2], point[2], pos_temp[2];
	var	v[2];
	var	prev_sel, sel;
	var	edge, edge1, edge2;
	var	pick, draw_flag = ON;
	var	i, j, key;
	var	mode, temp, mat;
	var	edges1, edges2;
	var	change_flag = OFF;
	var	vers, center;

	cur = Cursor();
	if (cur != PolyVertex( cur ))
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg1 );
		return ;
	}

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"回転中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【回転する辺を指定中】";
	DrawStatus();
	quit_flag = FALSE;

	prev_sel = Select();
	SelectAll( TRUE );
	if( SelectEdge( prev_sel, org ) == FALSE )
	{
		PopandClear( OVERWRITE );
		Select( prev_sel );
		return;
	}
	Status_title[0] = "【辺を回転中】";
	DrawStatus();
	sel = Select();
	edge = EdgeSelect();
	edge1 = EdgeVertex( edge, org[0] );
	edge1 = edge1 - Edge( org[0], org[1] );
	edge2 = EdgeVertex( edge, org[1] );
	edge2 = edge2 - Edge( org[0], org[1] );
	edges1 = Edges( edge1 );
	edges2 = Edges( edge2 );

	Select( prev_sel );
	center = (org[0]+org[1])*scale(UNIT_MATRIX, 0.5,0.5,0.5 );
	cur = Cursor();
	pick = cur;
	mode = 1;
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			v[0] = Position(org[mode]) - Position(center);
			v[1] = Position(cur) - Position(center);
			mat = CalRotMatrix( v[0], v[1] );
			pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
			pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if ( ShiftStat() & 1 )
		{
			cur = Cursor();
			TrimCursor( org[mode], MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
		{
			if( org[mode] == cur )
			{
				Warning();
				if( novice_flag == ON )
					Message( error_msg5 );
			}
			else
				break;
		}
		else if( key == ESC | key == BS | quit_flag == TRUE )
		{
			PopandClear( OVERWRITE );
			Select( prev_sel );
			return;
		}
		else if( key =='c' )
			change_flag = ON;
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			draw_flag = ON;
			v[0] = Position(org[mode]) - Position(center);
			v[1] = Position(pick) - Position(center);
			mat = CalRotMatrix( v[0], v[1] );
			pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
			pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		if( change_flag == ON )
			mode = 1 - mode;
		change_flag = OFF;
		input_flag = OFF;
	}

	Select( sel );
	v[0] = Position(org[mode]) - Position(center);
	v[1] = Position(pick) - Position(center);
	mat = CalRotMatrix( v[0], v[1] );
	pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
	pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
	for( i = 0; i< edges1; i++ )
	{
		EdgeGetVertex( edge1, i, point );
		if( point[0] == org[0] )
			DrawLine( pos_temp[0], point[1] );
		else
			DrawLine( pos_temp[0], point[0] );
	}
	for( i = 0; i< edges2; i++ )
	{
		EdgeGetVertex( edge2, i, point );
		if( point[0] == org[1] )
			DrawLine( pos_temp[1], point[1] );
		else
			DrawLine( pos_temp[1], point[0] );
	}
	DrawLine( pos_temp[0], pos_temp[1] );

	v[0] = Position(org[mode]) - Position(center);
	v[1] = Position(cur) - Position(center);
	mat = CalRotMatrix( v[0], v[1] );
	pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
	pos_temp[1] = center+(Position(org[1])-Position(center))*mat;

	v[0] = Position(pos_temp[0]) - Position(org[0]);
	v[1] = Position(pos_temp[1]) - Position(org[1]);
	SetPoly( org, v );
	Select( prev_sel );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

//
//	任意の２点を結ぶ線分を拡大縮小する
//
function _ScaleEdge()
{
	var	org[2], point[2], pos_temp[2];
	var	v[2];
	var	prev_sel, sel;
	var	edge, edge1, edge2;
	var	pick, draw_flag = ON;
	var	i, j, key;
	var	mode, temp, mat;
	var	edges1, edges2;
	var	change_flag = OFF;
	var	vers, center;

	cur = Cursor();
	if (cur != PolyVertex( cur ))
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg5 );
		return ;
	}

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"変形中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【拡大縮小する辺を指定中】";
	DrawStatus();
	quit_flag = FALSE;

	prev_sel = Select();
	SelectAll( TRUE );
	if( SelectEdge( prev_sel, org ) == FALSE )
	{
		PopandClear( OVERWRITE );
		Select( prev_sel );
		return;
	}
	Status_title[0] = "【辺を拡大縮小中】";
	DrawStatus();
	sel = Select();
	edge = EdgeSelect();
	edge1 = EdgeVertex( edge, org[0] );
	edge1 = edge1 - Edge( org[0], org[1] );
	edge2 = EdgeVertex( edge, org[1] );
	edge2 = edge2 - Edge( org[0], org[1] );
	edges1 = Edges( edge1 );
	edges2 = Edges( edge2 );

	Select( prev_sel );
	center = (org[0]+org[1])*scale(UNIT_MATRIX, 0.5,0.5,0.5 );
	cur = Cursor();
	pick = cur;
	mode = 1;
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			v[0] = Position(org[mode]) - Position(center);
			v[1] = (Position(cur) - Position(center))*(1.0/abs(v[0]));
			v[0] = unit(v[0]);
			mat = scale( UNIT_MATRIX, v[0].v[1], v[0].v[1], v[0].v[1]);
			pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
			pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if ( ShiftStat() & 1 )
		{
			cur = Cursor();
			TrimCursor( org[mode], MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
		{
			if( org[mode] == cur )
			{
				Warning();
				if( novice_flag == ON )
					Message( error_msg5 );
			}
			else
				break;
		}
		else if( key == ESC | key == BS | quit_flag == TRUE )
		{
			PopandClear( OVERWRITE );
			Select( prev_sel );
			return;
		}
		else if( key =='c' )
			change_flag = ON;
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			draw_flag = ON;
			v[0] = Position(org[mode]) - Position(center);
			v[1] = (Position(pick) - Position(center))*(1.0/abs(v[0]));
			v[0] = unit(v[0]);
			mat = scale( UNIT_MATRIX, v[0].v[1], v[0].v[1], v[0].v[1]);
			pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
			pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
			for( i = 0; i< edges1; i++ )
			{
				EdgeGetVertex( edge1, i, point );
				if( point[0] == org[0] )
					DrawLine( pos_temp[0], point[1] );
				else
					DrawLine( pos_temp[0], point[0] );
			}
			for( i = 0; i< edges2; i++ )
			{
				EdgeGetVertex( edge2, i, point );
				if( point[0] == org[1] )
					DrawLine( pos_temp[1], point[1] );
				else
					DrawLine( pos_temp[1], point[0] );
			}
			DrawLine( pos_temp[0], pos_temp[1] );
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		if( change_flag == ON )
			mode = 1 - mode;
		change_flag = OFF;
		input_flag = OFF;
	}

	Select( sel );
	v[0] = Position(org[mode]) - Position(center);
	v[1] = (Position(pick) - Position(center))*(1.0/abs(v[0]));
	v[0] = unit(v[0]);
	mat = scale( UNIT_MATRIX, v[0].v[1], v[0].v[1], v[0].v[1]);
	pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
	pos_temp[1] = center+(Position(org[1])-Position(center))*mat;
	for( i = 0; i< edges1; i++ )
	{
		EdgeGetVertex( edge1, i, point );
		if( point[0] == org[0] )
			DrawLine( pos_temp[0], point[1] );
		else
			DrawLine( pos_temp[0], point[0] );
	}
	for( i = 0; i< edges2; i++ )
	{
		EdgeGetVertex( edge2, i, point );
		if( point[0] == org[1] )
			DrawLine( pos_temp[1], point[1] );
		else
			DrawLine( pos_temp[1], point[0] );
	}
	DrawLine( pos_temp[0], pos_temp[1] );

	v[0] = Position(org[mode]) - Position(center);
	v[1] = (Position(cur) - Position(center))*(1.0/abs(v[0]));
	v[0] = unit(v[0]);
	mat = scale( UNIT_MATRIX, v[0].v[1], v[0].v[1], v[0].v[1]);
	pos_temp[0] = center+(Position(org[0])-Position(center))*mat;
	pos_temp[1] = center+(Position(org[1])-Position(center))*mat;

	v[0] = Position(pos_temp[0]) - Position(org[0]);
	v[1] = Position(pos_temp[1]) - Position(org[1]);
	SetPoly( org, v );
	Select( prev_sel );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}
